using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SmartMedical.WinUI
{
    /// <summary>
    /// 开西药处方窗体
    /// 用于医生为患者开具西药处方
    /// </summary>
    public partial class PrescribeWesternMedicineForm : Form
    {
        #region 私有字段
        /// <summary>
        /// HTTP客户端，用于API调用
        /// </summary>
        private readonly HttpClient _httpClient;
        
        /// <summary>
        /// API基础地址 - 写API端口
        /// </summary>
        private readonly string _apiBaseUrl = "http://localhost:5165";
        
        /// <summary>
        /// 患者ID
        /// </summary>
        private long _patientId;
        
        /// <summary>
        /// 患者姓名
        /// </summary>
        private string _patientName;
        
        /// <summary>
        /// 药品列表
        /// </summary>
        private List<MedicineItem> _medicines;
        #endregion

        #region 构造函数
        /// <summary>
        /// 初始化开西药窗体
        /// </summary>
        public PrescribeWesternMedicineForm()
        {
            InitializeComponent();
            _httpClient = new HttpClient();
            _medicines = new List<MedicineItem>();
            InitializeForm();
        }
        
        /// <summary>
        /// 初始化开西药窗体（带患者信息）
        /// </summary>
        /// <param name="patientId">患者ID</param>
        /// <param name="patientName">患者姓名</param>
        public PrescribeWesternMedicineForm(long patientId, string patientName) : this()
        {
            _patientId = patientId;
            _patientName = patientName;
            
            // 显示患者信息
            lblPatientIdValue.Text = patientId.ToString();
            lblPatientNameValue.Text = patientName;
            
            // 设置窗体标题
            this.Text = $"开西药 - {patientName}";
        }
        #endregion

        #region 初始化方法
        /// <summary>
        /// 初始化窗体
        /// </summary>
        private void InitializeForm()
        {
            // 初始化下拉框
            InitializeComboBoxes();
            
            // 设置DataGridView
            InitializeDataGridView();
            
            // 设置窗体属性
            this.AcceptButton = btnSave;
            this.CancelButton = btnCancel;
        }
        
        /// <summary>
        /// 初始化下拉框数据
        /// </summary>
        private void InitializeComboBoxes()
        {
            // 初始化用药频次下拉框
            cmbFrequency.Items.AddRange(new string[]
            {
                "每日一次",
                "每日两次",
                "每日三次",
                "每日四次",
                "每8小时一次",
                "每12小时一次",
                "睡前一次",
                "必要时服用"
            });
            
            // 初始化用法下拉框
            cmbUsage.Items.AddRange(new string[]
            {
                "口服",
                "含服",
                "嚼服",
                "外用",
                "滴眼",
                "滴鼻",
                "喷雾",
                "注射",
                "静脉滴注",
                "肌肉注射"
            });
            
            // 设置默认值
            cmbFrequency.SelectedIndex = 0;
            cmbUsage.SelectedIndex = 0;
        }
        
        /// <summary>
        /// 初始化DataGridView
        /// </summary>
        private void InitializeDataGridView()
        {
            dgvMedicines.AutoGenerateColumns = false;
            dgvMedicines.AllowUserToAddRows = false;
            dgvMedicines.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dgvMedicines.MultiSelect = false;
        }
        #endregion

        #region 事件处理方法
        /// <summary>
        /// 添加药品按钮点击事件
        /// </summary>
        /// <param name="sender">事件发送者</param>
        /// <param name="e">事件参数</param>
        private void BtnAddMedicine_Click(object sender, EventArgs e)
        {
            try
            {
                // 验证输入
                if (!ValidateMedicineInput())
                {
                    return;
                }
                
                // 创建药品项
                var medicine = new MedicineItem
                {
                    MedicineName = txtMedicineName.Text.Trim(),
                    Specification = txtSpecification.Text.Trim(),
                    Dosage = txtDosage.Text.Trim(),
                    Frequency = cmbFrequency.Text,
                    Duration = txtDuration.Text.Trim(),
                    Usage = cmbUsage.Text,
                    Remark = txtRemark.Text.Trim()
                };
                
                // 添加到列表
                _medicines.Add(medicine);
                
                // 刷新DataGridView
                RefreshMedicineList();
                
                // 清空输入框
                ClearMedicineInput();
                
                MessageBox.Show("药品添加成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"添加药品失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        
        /// <summary>
        /// 删除药品按钮点击事件
        /// </summary>
        /// <param name="sender">事件发送者</param>
        /// <param name="e">事件参数</param>
        private void BtnRemoveMedicine_Click(object sender, EventArgs e)
        {
            try
            {
                if (dgvMedicines.SelectedRows.Count == 0)
                {
                    MessageBox.Show("请选择要删除的药品", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                
                var result = MessageBox.Show("确定要删除选中的药品吗？", "确认删除", 
                    MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                
                if (result == DialogResult.Yes)
                {
                    int selectedIndex = dgvMedicines.SelectedRows[0].Index;
                    _medicines.RemoveAt(selectedIndex);
                    RefreshMedicineList();
                    
                    MessageBox.Show("药品删除成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"删除药品失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        
        /// <summary>
        /// 保存按钮点击事件
        /// </summary>
        /// <param name="sender">事件发送者</param>
        /// <param name="e">事件参数</param>
        private async void BtnSave_Click(object sender, EventArgs e)
        {
            try
            {
                // 验证处方信息
                if (!ValidatePrescription())
                {
                    return;
                }
                
                // 禁用保存按钮，防止重复提交
                btnSave.Enabled = false;
                btnSave.Text = "保存中...";
                
                // 保存处方
                bool success = await SavePrescriptionAsync();
                
                if (success)
                {
                    MessageBox.Show("西药处方保存成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    this.DialogResult = DialogResult.OK;
                    this.Close();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"保存处方失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                // 恢复保存按钮状态
                btnSave.Enabled = true;
                btnSave.Text = "保存";
            }
        }
        
        /// <summary>
        /// 取消按钮点击事件
        /// </summary>
        /// <param name="sender">事件发送者</param>
        /// <param name="e">事件参数</param>
        private void BtnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }
        #endregion

        #region 验证方法
        /// <summary>
        /// 验证药品输入
        /// </summary>
        /// <returns>验证是否通过</returns>
        private bool ValidateMedicineInput()
        {
            if (string.IsNullOrWhiteSpace(txtMedicineName.Text))
            {
                MessageBox.Show("请输入药品名称", "验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtMedicineName.Focus();
                return false;
            }
            
            if (string.IsNullOrWhiteSpace(txtSpecification.Text))
            {
                MessageBox.Show("请输入药品规格", "验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtSpecification.Focus();
                return false;
            }
            
            if (string.IsNullOrWhiteSpace(txtDosage.Text))
            {
                MessageBox.Show("请输入药品剂量", "验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtDosage.Focus();
                return false;
            }
            
            if (cmbFrequency.SelectedIndex == -1)
            {
                MessageBox.Show("请选择用药频次", "验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                cmbFrequency.Focus();
                return false;
            }
            
            if (string.IsNullOrWhiteSpace(txtDuration.Text))
            {
                MessageBox.Show("请输入疗程", "验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtDuration.Focus();
                return false;
            }
            
            if (cmbUsage.SelectedIndex == -1)
            {
                MessageBox.Show("请选择用法", "验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                cmbUsage.Focus();
                return false;
            }
            
            return true;
        }
        
        /// <summary>
        /// 验证处方信息
        /// </summary>
        /// <returns>验证是否通过</returns>
        private bool ValidatePrescription()
        {
            if (string.IsNullOrWhiteSpace(txtDiagnosis.Text))
            {
                MessageBox.Show("请输入诊断信息", "验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtDiagnosis.Focus();
                return false;
            }
            
            if (_medicines.Count == 0)
            {
                MessageBox.Show("请至少添加一种药品", "验证失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            
            return true;
        }
        #endregion

        #region 辅助方法
        /// <summary>
        /// 刷新药品列表显示
        /// </summary>
        private void RefreshMedicineList()
        {
            dgvMedicines.Rows.Clear();
            
            foreach (var medicine in _medicines)
            {
                dgvMedicines.Rows.Add(
                    medicine.MedicineName,
                    medicine.Specification,
                    medicine.Dosage,
                    medicine.Frequency,
                    medicine.Duration,
                    medicine.Usage,
                    medicine.Remark
                );
            }
        }
        
        /// <summary>
        /// 清空药品输入框
        /// </summary>
        private void ClearMedicineInput()
        {
            txtMedicineName.Clear();
            txtSpecification.Clear();
            txtDosage.Clear();
            txtDuration.Clear();
            txtRemark.Clear();
            cmbFrequency.SelectedIndex = 0;
            cmbUsage.SelectedIndex = 0;
            txtMedicineName.Focus();
        }
        
        /// <summary>
        /// 保存处方到服务器
        /// </summary>
        /// <returns>保存是否成功</returns>
        private async Task<bool> SavePrescriptionAsync()
        {
            try
            {
                // 创建处方数据，匹配后端API的数据结构
                var prescriptionData = new WesternMedicinePrescriptionData
                {
                    PatientId = _patientId,
                    PatientName = _patientName,
                    Diagnosis = txtDiagnosis.Text.Trim(),
                    Remark = txtPrescriptionRemark.Text.Trim(),
                    Medicines = _medicines,
                    Doctor = Properties.Settings.Default.DisplayName ?? "当前医生" // 从登录信息获取医生姓名
                };
                
                string jsonData = JsonSerializer.Serialize(prescriptionData, new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                    Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
                });
                
                var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
                var response = await _httpClient.PostAsync($"{_apiBaseUrl}/api/Medical/CreateWesternMedicinePrescription", content);
                
                if (response.IsSuccessStatusCode)
                {
                    var responseContent = await response.Content.ReadAsStringAsync();
                    var result = JsonSerializer.Deserialize<SavePrescriptionResult>(responseContent, new JsonSerializerOptions
                    {
                        PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                    });
                    
                    if (result?.Code == 200)
                    {
                        return true;
                    }
                    else
                    {
                        MessageBox.Show($"保存失败：{result?.Msg ?? "未知错误"}", "错误", 
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return false;
                    }
                }
                else
                {
                    MessageBox.Show($"网络请求失败：{response.StatusCode}", "错误", 
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"保存处方时发生错误：{ex.Message}", "错误", 
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }
        #endregion

        #region 资源释放
        /// <summary>
        /// 释放HttpClient资源
        /// </summary>
        private void DisposeHttpClient()
        {
            _httpClient?.Dispose();
        }
        #endregion
    }

    #region 数据模型类
    /// <summary>
    /// 药品项数据模型
    /// </summary>
    public class MedicineItem
    {
        /// <summary>
        /// 药品名称
        /// </summary>
        public string MedicineName { get; set; } = string.Empty;
        
        /// <summary>
        /// 规格
        /// </summary>
        public string Specification { get; set; } = string.Empty;
        
        /// <summary>
        /// 剂量
        /// </summary>
        public string Dosage { get; set; } = string.Empty;
        
        /// <summary>
        /// 频次
        /// </summary>
        public string Frequency { get; set; } = string.Empty;
        
        /// <summary>
        /// 疗程
        /// </summary>
        public string Duration { get; set; } = string.Empty;
        
        /// <summary>
        /// 用法
        /// </summary>
        public string Usage { get; set; } = string.Empty;
        
        /// <summary>
        /// 备注
        /// </summary>
        public string Remark { get; set; } = string.Empty;
    }
    
    /// <summary>
    /// 西药处方数据模型
    /// </summary>
    public class WesternMedicinePrescriptionData
    {
        /// <summary>
        /// 患者ID
        /// </summary>
        public long PatientId { get; set; }
        
        /// <summary>
        /// 患者姓名
        /// </summary>
        public string PatientName { get; set; } = string.Empty;
        
        /// <summary>
        /// 诊断
        /// </summary>
        public string Diagnosis { get; set; } = string.Empty;
        
        /// <summary>
        /// 备注
        /// </summary>
        public string Remark { get; set; } = string.Empty;
        
        /// <summary>
        /// 药品列表
        /// </summary>
        public List<MedicineItem> Medicines { get; set; } = new List<MedicineItem>();
        
        /// <summary>
        /// 医生
        /// </summary>
        public string Doctor { get; set; } = string.Empty;
    }
    
    /// <summary>
    /// 保存处方结果模型
    /// </summary>
    public class SavePrescriptionResult
    {
        /// <summary>
        /// 状态码
        /// </summary>
        public int Code { get; set; }
        
        /// <summary>
        /// 消息
        /// </summary>
        public string Msg { get; set; } = string.Empty;
        
        /// <summary>
        /// 数据
        /// </summary>
        public string Data { get; set; } = string.Empty;
    }
    #endregion
}